﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace OA.Mvc3.Controllers
{
    [ValidateInput(false)]
    public class ChatController :UI.BaseController
    {
        protected override bool IsPerformance { get { return false; } }

        public const string ProgrameCode = "Chat";
        public static readonly string currentPath = UI.Utils.GetCurrentPath(ProgrameCode);

        public ChatController()
        {
            ViewBag.CurrentPath = currentPath;
        }

        [UI.ValidateAuthority(ProgrameCode , "manage")]
        public ActionResult Index()
        {
            return View();
        }

        private object ToJsonObject(Model.Chat value)
        {
            return new
                {
                    ID = value.ID,
                    SendUserName = value.SendUserName,
                    SendRealName = value.Send.RealName,
                    ReceivedUserName = value.ReceivedUserName,
                    ReceivedRealName = value.Received.RealName,
                    SendTime = UI.Utils.FormateDate(value.SendTime),
                    IsReceived = value.IsReceived,
                    Message = value.Message
                };
        }

        [UI.ValidateAuthority(ProgrameCode , "manage")]
        public string List(int page, int rows, string sort, string order)
        {
            string where = Common.HqlQeuryHelp.GetWhere(typeof(Model.Chat), "SendUserName,ReceivedUserName,SendTime");
            string orderby = "ID desc";
            if (!string.IsNullOrEmpty(sort)) orderby = sort + " " + order;

            var bll = new BLL.Chat();
            var list = bll.Get(where, orderby, (page - 1) * rows, rows);
            List<object> listView = new List<object>();
            foreach (var i in list)
            {
                listView.Add(ToJsonObject(i));
            }
            var ret = new
            {
                total=bll.GetCount(where),
                rows = listView
            };
            return UI.Utils.ToJsonString(ret);
        }


        [UI.ValidateAuthority(ProgrameCode , "delete")]
        public string Delete(string id)
        {
            var ret = new BLL.Chat().Delete(id);
            return UI.Utils.ToJsonString(ret);
        }

        [UI.LoginValidate]
        public ActionResult ChatWindow()
        {
            ViewBag.OnLineCount = BLL.LoginUser.OnLineManagers.Where(r => r.IsKick == false).GroupBy(r => r.UserName).Count();
            ViewBag.AllCount = new BLL.Manager().GetCount(null);
            ViewBag.received = new BLL.Authority().ValidateAuthority(Common.EnumType.ResourceType.Button, Common.Keys.WebSiteCode, "Chat","received", BLL.LoginUser.LoginManager.UserName).success;
            return View();
        }

        [UI.LoginValidate]
        public string ChatManagerList(string id)
        {
            string where = null;
            List<object> ps = new List<object>();
            if (string.IsNullOrEmpty(id))
            {
                where = "it.ParentID is null";
            }
            else
            {
                where = "it.ParentID=?";
                ps.Add(id);
            }
            var ret = new BLL.ManagerGroup().Get(where, null, 0, 0, ps.ToArray());
            List<object> trees = new List<object>();
            foreach (var i in ret)
            {
                string groupName = i.GroupName;
                int onlines = 0;
                foreach (var m in i.Managers)
                {
                    if (BLL.LoginUser.IsOnLine(m.UserName))
                    {
                        onlines++;
                    }
                }
                if (i.Managers.Count > 0)
                {
                    groupName += "(" + onlines + "/" + i.Managers.Count + ")";
                }
                trees.Add(new
                {
                    id = i.ID,
                    //iconCls = "icon-group",
                    text = groupName,
                    state = i.Childs.Count > 0 || i.Managers.Count > 0 ? "closed" : null,
                    attributes = new { type = "group" }
                });
            }

            ps.Clear();
            if (id == null)
            {
                where = "it.GroupID is null";
            }
            else
            {
                where = "it.GroupID=?";
                ps.Add(id);
            }
            var managerlist = new BLL.Manager().Get(where, null, 0, 0,ps.ToArray());
            foreach (var i in managerlist)
            {

                trees.Add(new
                {
                    id = i.UserName,
                    iconCls = BLL.LoginUser.IsOnLine(i.UserName)? "icon-user" : "icon-user-gray",
                    text = i.RealName + " (" + i.UserName + ")",
                    attributes = new { type = "manager" }
                });
            }
            return UI.Utils.ToJsonString(trees);
        }

        [UI.ValidateAuthority(ProgrameCode , "send")]
        public ActionResult Send()
        {
            return View();
        }

        [HttpPost]
        [UI.ValidateAuthority(ProgrameCode , "send")]
        public string Send(string ReceivedUserName, string Message)
        {
            Model.Chat chatModel;
            var ret = new BLL.Chat().Send(ReceivedUserName, Message, out chatModel);
            if (ret.success)
            {
                ret.message = "发送成功";
                UI.Comet.NotifyMsg(ReceivedUserName, new List<Model.Chat>() { chatModel });
            }
            return UI.Utils.ToJsonString(ret);
        }

        [UI.ValidateAuthority(ProgrameCode , "history")]
        public ViewResult History(string userName, int page,int rows)
        {
            var where="(it.SendUserName=? and it.ReceivedUserName=?) or (it.SendUserName=? and it.ReceivedUserName=?)";
            var chat=new BLL.Chat();
            var list = chat.Get(where
                , "it.ID asc", (page - 1) * rows, rows
                , userName, BLL.LoginUser.LoginManager.UserName, BLL.LoginUser.LoginManager.UserName, userName);


            var count=chat.GetCount(where,userName, BLL.LoginUser.LoginManager.UserName, BLL.LoginUser.LoginManager.UserName, userName);
            ViewBag.PageLink = UI.Utils.GetPageLink(page, rows, count, "userName", userName);
            return View(list);
        }
    }

    #region 接收消息
    [SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)] //设置session为只读，否则会锁定session造成阻塞
    [UI.SecurityCheck]
    public class ChatReceivedController : AsyncController
    {
        /// <summary>
        /// 接收当前用户的消息
        /// </summary>
        /// <returns></returns>
        [UI.ValidateAuthority("Chat","received")]
        [AsyncTimeout(-1)]
        public void IndexAsync()
        {
            UI.Comet.WaitMsg(BLL.LoginUser.LoginManager.UserName, AsyncManager);
            var list = new BLL.Chat().Received();
            if (list.Count > 0)
            {
                UI.Comet.NotifyMsg(BLL.LoginUser.LoginManager.UserName, list);
            }
            else
            {
                BLL.DB_help.NHibernateHelper.CloseAllSession(); //关闭数据库连接，以免占用
            }
        }

        public string IndexCompleted(IList<Model.Chat> Data)
        {
            List<object> listView = new List<object>();
            if (Data != null && Data.Count > 0)
            {
                var bll = new BLL.Chat();
                foreach (var i in Data)
                {
                    listView.Add(ToJsonObject(i));
                    bll.SetIsReceived(i.ID);
                }
            }
            return UI.Utils.ToJsonString(listView);
        }
        private object ToJsonObject(Model.Chat value)
        {
            return new
            {
                ID = value.ID,
                SendUserName = value.SendUserName,
                SendRealName = value.Send.RealName,
                ReceivedUserName = value.ReceivedUserName,
                ReceivedRealName = value.Received.RealName,
                SendTime = UI.Utils.FormateDate(value.SendTime),
                IsReceived = value.IsReceived,
                Message = value.Message
            };
        }

        protected override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            if (filterContext.Exception != null && filterContext.ExceptionHandled ==false
                && filterContext.Exception is TimeoutException 
                && filterContext.ActionDescriptor.ActionName == "Index") //捕获index超时
                {
                    filterContext.Result = Content(IndexCompleted(null));
                    filterContext.ExceptionHandled = true;
                }
            base.OnActionExecuted(filterContext);
        }
    }
   #endregion 
}
